/*
 * @copyright: Huang Ding
 * @Author: ding-cx
 * @Date: 2022-04-26 14:13:53
 * @LastEditors: ding-cx
 * @LastEditTime: 2022-04-29 12:07:28
 * @Description: file content
 */

import { Dingtalk } from "../dingtalk";
import CodoBase from "../../CodoBase";
import { Application } from "egg";
import TokenService from "./TokenService";

// const cacheConfigName = Symbol("cache#dingTalkConfig");

export default class DingTalkBasePublicService extends CodoBase {
	constructor(app: Application, public readonly config: Dingtalk.AppConfig) {
		super(app);
	}

	public readonly tokenService = new TokenService(this.app, this.config);

	/** 拼接api接口url的access_token参数
	 * - 旧版接口
	 */
	async getURL(url: string) {
		const token = await this.tokenService.getOVAccessToken();
		return `${url}?access_token=${token}`;
	}

	/**
	 *
	 * 新版钉钉接口的统一封装请求方法
	 * - 新版接口
	 * - 获取token的操作不能调用本接口，本接口默认已拿到token，只有实际业务逻辑需要调用本接口。
	 *
	 * @param {string} url 资源部分，不含前面的域名；以/开头；query参数自行拼接在后面
	 * @param {dingTalk.dingTalk.INewVersionRequestParams} params
	 * @return {*}
	 * @memberof DingTalkBasePublicService
	 */
	async nvRequest<T>(url: string, params: Dingtalk.nv.request.IRequestParams) {
		const access_token = await this.tokenService.getNVAccessToken();
		this.app.coreLogger.debug(`nv token %s`, access_token);
		const host = `https://api.dingtalk.com`;
		url = `${host}${url.trim()}`;
		const header = params.header || {};
		header["x-acs-dingtalk-access-token"] = access_token;

		const res = await this.curl<T | Dingtalk.nv.response.IErrorResponse>(url, {
			contentType: "json",
			dataType: "json",
			method: params.method,
			headers: header,
			data: params.data || undefined,
		});
		this.nvcheckError(url, res);
		return res.data as T;
	}

	/**
	 *
	 *旧版规范 判断钉钉接口返回的结果，是否调用错误。errcode大于0
	 *
	 * @param {*} url
	 * @param {dingTalk.IResponseCommon} data
	 * @memberof DingTalkBasePublicService
	 */
	protected ovcheckError(url, res: { data: Dingtalk.ov.IResponseCommon; status: number }) {
		if (res.status !== 200) {
			this.app.coreLogger.error("dingTalk 请求响应状态非200 接口url %s", url);
			throw new Error(`dingTalk 请求接口 ${url} 响应异常！`);
		}
		if (res.data.errcode !== 0) {
			this.app.coreLogger.error(
				"dingtalk旧版接口返回errcode !== 0  \r\n请求的url：%s \r\n错误码：%s \r\n错误原因：%s",
				url,
				res.data.errcode,
				res.data.errmsg
			);
			throw new Error(`dingTalk 旧版接口 业务响应错误 响应码：${res.data.errcode} 描述：${res.data.errmsg}`);
		}
	}

	/**
	 *新版规范api 检查响应结果
	 *
	 * @param {*} url
	 * @param {{ data: dingTalk.IResponseNewVersionGetAccessToken; status: number }} res
	 * @memberof DingTalkBasePublicService
	 */
	protected nvcheckError(url, res: { data: any; status: number }) {
		if (res.status !== 200) {
			const data2 = res.data as Dingtalk.nv.response.IErrorResponse;
			this.app.coreLogger.error(
				"dingTalk 新版接口响应异常！\r\n请求的url：%s \r\n错误码 %s \r\n错误原因：%s",
				url,
				data2.code,
				data2.message || "未知原因"
			);
			throw new Error(`dingTalk 新版接口响应异常！ url:${url} code:${data2.code} message:${data2.message}`);
		}
	}
}
